#!/usr/local/bin/python2.7

from xml.etree.ElementTree import Element, ElementTree
from xmlwriter import *
from constants import *

class XMLdb(object):

    def __init__(self):
        self._root = None
        self._writer = XMLWriter()
        self._components = []
        self._dst = ''

        self._dst_dir = Constants.logs_dir
        self._name = 'mycmdb'
        self._extension = 'xml'

    def addComponent(self, comp):
        self._components.append(comp)

    def addComponents(self, comps):
        self._components.extend(comps)

    def _buildDst(self):
        name = self._name + '.' + self._extension
        self._dst = os.path.join(self._dst_dir, name)

    def saveFile(self):
        self._root = Element('cmdbase')
        self._buildElement()
        self._buildDst()

        tree = ElementTree(element = self._root)
        with open(self._dst, 'w') as myfile:
            tree.write(myfile)

        self._cleanXML()

    def _buildElement(self):
        for comp in self._components:
            self._writer.component = comp
            elem = self._writer.xml_element
            self._root.append(elem)

    def _cleanXML(self):
        """
        Takes an xml file and adds line breaks and (expanded) tabs to
        reflect the xml data hierarchy.

        This function is really a thin wrapper around the borrowed code of
        the *_indent* function defined below.
        """

        tree = ElementTree()
        tree.parse(self._dst) # load in the existing xml
        self._indent(tree.getroot()) # reformat it
        tree.write(self._dst, "utf-8") # rewrite it

    def _indent(self, elem, level = 0):
        """
        A recursive function that formats an xml.etree.ElementTree.Element
        object with line breaks and (expanded) tabs to reflect the xml data
        hierarchy.
        """

        tab_width = 2

        i = "\n" + level*tab_width*' '
        b = tab_width*' '
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + b
            for e in elem:
                self._indent(e, level + 1)
                if not e.tail or not e.tail.strip():
                    e.tail = i + b
            if not e.tail or not e.tail.strip():
                e.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i

